/*
 * Copyright (c) 2017 <l_iupeiyu@qq.com> All rights reserved.
 */

package com.gzwh.v1.sysapi.shiro;

import com.gzwh.v1.sysapi.core.jwt.JwtConfig;
import com.gzwh.v1.sysapi.core.jwt.JwtUtil;
import com.gzwh.v1.sysapi.dao.member.MemberMapper;
import com.gzwh.v1.sysapi.entity.UserBean;
import com.gzwh.v1.sysapi.entity.member.SFMemberEntity;
import com.gzwh.v1.sysapi.server.member.impl.MemberServerImpl;
import com.gzwh.v1.sysapi.utils.JWTUtil;
import io.jsonwebtoken.Claims;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Map;

/**
 * author geekcattle
 * date 2017/3/13 0013 下午 16:55
 */

@Component
public class CustomModularRealmAuthenticator extends ModularRealmAuthenticator {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private Map<String, Object> definedRealms;
    @Autowired
    MemberMapper memberMapper;
    @Autowired
    private JwtConfig jwtConfig;

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private StringRedisTemplate stringRedisTemplate = null;

    /**
     * 多个realm实现
     */
    @Override
    protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
        return super.doMultiRealmAuthentication(realms, token);
    }

    /**
     * 调用单个realm执行操作
     */
    @Override
    protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) throws AuthenticationException {

        // 如果该realms不支持(不能验证)当前token
        if (!realm.supports(token)) {
            throw new ShiroException("token错误!");
        }
        AuthenticationInfo info = null;

        info = realm.getAuthenticationInfo(token);
        if (info == null) {
            throw new ShiroException("token不存在!");
        }

        return info;
    }


    /**
     * 判断登录类型执行操作
     */
    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        this.assertRealmsConfigured();
//        System.out.println("456");
        Realm realm = null;
//        if (authenticationToken.getClass().getName().equals("com.gzwh.v1.sysapi.shiro.JWTToken")) {
//
//            String token = (String) authenticationToken.getCredentials();
//            Claims claims = jwtUtil.parseJWT(token, jwtConfig.getSecret());
//            if (stringRedisTemplate.opsForValue().get("type:member:" + token) == null) {
//                throw new ShiroException("token invalid");
//            }
//            String username = claims.getSubject();
//            if (username == null) {
//                throw new ShiroException("token invalid");
//            }
////            memberMapper.selectSFMemberByName("admin4");
////            SFMemberEntity userInfo = memberMapper.selectSFMemberByName(username);
////            if (userInfo == null) {
////                throw new AuthenticationException("User didn't existed!");
////            }
////            if (JWTUtil.verify(token, username, "123123")) {
////                throw new AuthenticationException("Username or password error");
////            realm = (Realm) this.definedRealms.get("customShiroRealm");
////                return new SimpleAuthenticationInfo(token, token, "my_realm");
////            }
////            throw new AuthenticationException("Username or password error");
//            return new SimpleAuthenticationInfo(token, token, "my_realm");
//        } else {


        CustomerAuthenticationToken token = (CustomerAuthenticationToken) authenticationToken;

//        if (token.getLoginForm() != null && token.getLoginForm().length() > 6) {
//            String tokens = token.getLoginForm();
//            if (stringRedisTemplate.opsForValue().get("type:member:" + tokens) == null) {
//                throw new ShiroException("token invalid");
//            }
//        }
        //判断是否是后台用户
        if (token.getLoginType().equals("1")) {
            realm = (Realm) this.definedRealms.get("customShiroRealm");
        } else {
            realm = (Realm) this.definedRealms.get("adminShiroRealm");
        }
        return this.doSingleRealmAuthentication(realm, authenticationToken);
//        }
    }

    /**
     * 判断realm是否为空
     */
    @Override
    protected void assertRealmsConfigured() throws IllegalStateException {
        this.definedRealms = this.getDefinedRealms();
        if (CollectionUtils.isEmpty(this.definedRealms)) {
            throw new ShiroException("值传递错误!");
        }
    }

    public Map<String, Object> getDefinedRealms() {
        return this.definedRealms;
    }

    public void setDefinedRealms(Map<String, Object> definedRealms) {
        this.definedRealms = definedRealms;
    }

}
